<?php
/**
 * Created by PhpStorm.
 * User: Rain
 * Date: 2019/11/21
 * Time: 15:23
 */

namespace app\service\alone\Upload;


use app\admin\validate\Upload;
use app\service\alone\BaseService;
use app\service\interfaces\EncryptionInterface;
use think\facade\Filesystem;

class UploadService extends BaseService
{
    /** @var EncryptionInterface */
    private $encryption;

    /***
     * 上传图片
     *
     * @param $file
     * @param EncryptionInterface $encryption
     * @return array
     * @throws \Exception
     */
    public function uploadImg($file, EncryptionInterface $encryption)
    {
        $this->encryption = $encryption;

        return $this->upload($file, 'images', true);
    }

    /***
     * 上传视频
     *
     * @param $file
     * @param EncryptionInterface $encryption
     * @return array
     * @throws \Exception
     */
    public function uploadVideo($file, EncryptionInterface $encryption)
    {
        $this->encryption = $encryption;

        return $this->upload($file, 'videos', true);
    }

    /***
     * 上传文件
     *
     * @param $file
     * @param EncryptionInterface $encryption
     * @return array
     * @throws \Exception
     */
    public function uploadFile($file, EncryptionInterface $encryption)
    {
        $this->encryption = $encryption;

        return $this->upload($file, 'files', true);
    }

    /**
     * 上传资源
     *
     * @param $file
     * @param $field
     * @param $isTemp
     * @return array
     * @throws \Exception
     */
    private function upload($file, $field, $isTemp)
    {
        list($location, $isPath) = [config('filesystem.location'), config('app.path')];

        $path = ($isTemp ? $location['tmp'] : $location['real']) . DIRECTORY_SEPARATOR . $field . DIRECTORY_SEPARATOR . date('Y-m-d');

        $path = str_replace("\\", '/', Filesystem::disk('public')->putFile($path, $file, 'sha1'));

        return [
            'input' => $isPath ? $this->encryption->encryption($path) : $path,
        ];
    }

    /**
     * 分片上传
     *
     * @param string $action
     * @return array
     */
    public function multipart(string $action): array
    {
        // 分片上传规则对应方法和参数
        $rules = [
            'key' => [
                'action' => 'generateUploadFileKey',
                'params' => [
                    'name' => request()->param('name'),
                    'size' => (int)request()->param('size'),
                    'totalSheet' => (int)request()->param('totalSheet'),
                ],
                'method' => 'GET',
            ],
            'upload' => [
                'action' => 'upload',
                'params' => [
                    'key' => request()->param('key'),
                    'md5' => request()->param('md5'),
                    'index' => (int)request()->param('index'),
                    'block' => request()->file('block'),
                ],
                'method' => 'POST',
            ],
            'reset' => [
                'action' => 'reset',
                'params' => [
                    'key' => request()->param('key'),
                    'indexList' => request()->param('indexList'),
                ],
                'method' => 'POST',
            ],
            'cancel' => [
                'action' => 'cancel',
                'params' => [
                    'key' => request()->param('key'),
                ],
                'method' => 'POST',
            ]
        ];

        // 规则是否存在
        if (!isField($rules, $action)) return echoArr(500, '路由规则错误，请检查你的url');

        // 请求方式是否正确
        if ($rules[$action]['method'] !== request()->method()) return echoArr(500, '路由请求方式错误');

        // 验证参数
        validate(Upload::class . ".{$rules[$action]['action']}")->check($rules[$action]['params']);

        // 调用的方法
        return call_user_func_array([FragmentationService::getInstance(), $rules[$action]['action']], array_values($rules[$action]['params']));
    }
}
